package cn.itsource.pethome.order.service.impl;

import cn.itsource.pethome.basic.domain.Point;
import cn.itsource.pethome.basic.service.impl.BaseServiceImpl;
import cn.itsource.pethome.basic.util.CodeGenerateUtils;
import cn.itsource.pethome.basic.util.DistanceUtil;
import cn.itsource.pethome.order.domain.OrderAddress;
import cn.itsource.pethome.order.domain.ProductOrder;
import cn.itsource.pethome.order.domain.ProductOrderDetail;
import cn.itsource.pethome.order.domain.UserAddress;
import cn.itsource.pethome.order.mapper.OrderAddressMapper;
import cn.itsource.pethome.order.mapper.ProductOrderDetailMapper;
import cn.itsource.pethome.order.mapper.ProductOrderMapper;
import cn.itsource.pethome.order.mapper.UserAddressMapper;
import cn.itsource.pethome.order.service.IProductOrderService;
import cn.itsource.pethome.org.domain.Product;
import cn.itsource.pethome.org.domain.Shop;
import cn.itsource.pethome.org.mapper.ProductMapper;
import cn.itsource.pethome.org.mapper.ShopMapper;
import cn.itsource.pethome.pay.constant.PayConstants;
import cn.itsource.pethome.pay.domain.PayBill;
import cn.itsource.pethome.pay.service.IPayBillService;
import cn.itsource.pethome.quartz.domain.QuartzJobInfo;
import cn.itsource.pethome.quartz.service.IQuartzService;
import cn.itsource.pethome.user.domain.User;
import org.apache.ibatis.annotations.Param;
import org.quartz.ee.jmx.jboss.QuartzService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.params.Params;

import java.math.BigDecimal;
import java.util.*;

/**
 * @description: 描述:
 * @date: 2020/8/26 16:28
 * @author: summer
 * version: 1.0
 */
@Service
public class ProductOrderServiceImpl extends BaseServiceImpl<ProductOrder> implements IProductOrderService {

    @Autowired
    private IQuartzService quartzService;

    //服务订单明细mapper
    @Autowired
    private ProductOrderDetailMapper productOrderDetailMapper;

    //订单地址mapper
    @Autowired
    private OrderAddressMapper orderAddressMapper;

    //服务订单mapper
    @Autowired
    private ProductOrderMapper productOrderMapper;

    //用户地址mapper
    @Autowired
    private UserAddressMapper userAddressMapper;

    //门店mapper
    @Autowired
    private ShopMapper shopMapper;

    //服务mapper
    @Autowired
    private ProductMapper productMapper;

    //支付单
    @Autowired
    private IPayBillService payBillService;

    @Override
    public String submitOrder(User user, Map<String, Object> partm) {
        //获取用户地址id
        Integer addressId = (Integer) partm.get("addressId");
        //支付方式
        Integer payType = (Integer) partm.get("payType");
        //获取产品服务（产品服务id，数量）
        List<Map<String,Object>> products = (List<Map<String,Object>>) partm.get("products");
        //通过用户地址id把用户地址对象查询出来
        UserAddress userAddress = userAddressMapper.loadById(Long.valueOf(addressId));
        //获取用户的地址
        String fullAddress = userAddress.getFullAddress();
        //根据地址获取经纬度
        Point point = DistanceUtil.getPoint(fullAddress);
        //获取最近的店铺
        Shop shop = DistanceUtil.getNearestShop(point, shopMapper.findDepartment());
        //创建服务订单
        ProductOrder productOrder = createProductOrder(shop,products,user,payType);
        //保存服务订单
        productOrderMapper.save(productOrder);
        //保存服务订单明细
        List<ProductOrderDetail> productOrderDetail = createProductOrderDetail(products,productOrder);
        //批量保存服务订单明细
        productOrderDetailMapper.batchSave(productOrderDetail);
        //把用户地址转为订单地址
        OrderAddress orderAddress = userAddress2OrderAddress(userAddress);
        orderAddress.setOrder(productOrder);
        orderAddress.setOrderSn(productOrder.getOrderSn());
        //保存订单地址
        orderAddressMapper.save(orderAddress);
        //创建支付单
        PayBill payBill = createPayBill(productOrder,payType);
        //保存支付单
        payBillService.save(payBill);
        //@TUDO   跳转到支付界面
        String form = payBillService.goPay(payBill);
        //@TUDO   创建定时器任务
        QuartzJobInfo jobInfo = createQuartzInfo(productOrder);
        quartzService.addJob(jobInfo);
        return form;
    }

    /**
     * 功能描述: 创建QuartzJobInfo对象
     * @param productOrder
     * @return: cn.itsource.pethome.quartz.domain.QuartzJobInfo
     * @Date: 2020/8/28
     */
    private QuartzJobInfo createQuartzInfo(ProductOrder productOrder) {
        QuartzJobInfo jobInfo = new QuartzJobInfo();
        jobInfo.setJobName(PayConstants.BUSINESSTYPE_PRODUCT+productOrder.getId());
        jobInfo.setFireDate(productOrder.getLastPayTime());
        jobInfo.setType(PayConstants.BUSINESSTYPE_PRODUCT);
        Map<String, Object> map = new HashMap<>();
        map.put("orderSn", productOrder.getOrderSn());
        jobInfo.setParams(map);
        return jobInfo;
    }

    /**
     * 功能描述: 创建支付订单
     * @param productOrder
     * @param payType
     * @return: PayBill
     * @Date: 2020/8/26
     */
    private PayBill createPayBill(ProductOrder productOrder, Integer payType) {
        PayBill payBill = new PayBill();
        //摘要
        payBill.setDigest(productOrder.getDigest());
        //金额
        payBill.setMoney(productOrder.getPrice());
        //支付状态  0 待支付      1已支付    -1 取消
        payBill.setState(0);
        //最后支付时间
        payBill.setLastPayTime(new Date(System.currentTimeMillis() + 15*60*1000));
        //余额
        payBill.setPayChannel(payType);
        //用户
        payBill.setUser(productOrder.getUser());
        //业务类型
        payBill.setBusinessType(PayConstants.BUSINESSTYPE_PRODUCT);
        //业务键
        payBill.setBusinessKey(productOrder.getId());
        //店铺
        payBill.setShop(productOrder.getShop());
        //订单编号
        payBill.setOrderSn(productOrder.getOrderSn());
        return payBill;
    }

    /**
     * 功能描述: 把用户地址转为订单地址
     * @param userAddress
     * @return: cn.itsource.pethome.order.domain.OrderAddress
     * @Date: 2020/8/26
     */
    private OrderAddress userAddress2OrderAddress(UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress,orderAddress );
        orderAddress.setCreateTime(new Date());
        return orderAddress;
    }

    /**
     * 功能描述: 创建服务订单明细
     * @param products
     * @param productOrder
     * @return: java.util.List<cn.itsource.pethome.org.domain.ProductDetail>
     * @Date: 2020/8/26
     */
    private List<ProductOrderDetail> createProductOrderDetail(List<Map<String, Object>> products, ProductOrder productOrder) {
        List<ProductOrderDetail> details = new ArrayList<>();
        ProductOrderDetail detail = new ProductOrderDetail();
        for (Map<String, Object> partm : products) {
            Integer id = (Integer) partm.get("id");
            Integer num = (Integer) partm.get("num");
            Product product = productMapper.loadById(Long.valueOf(id));
            detail.setProduct(product);
            detail.setSaleCount(num);
            detail.setOrder(productOrder);
        }
        details.add(detail);
        return details;
    }

    /**
     * 功能描述: 创建服务订单
     * @param shop
     * @param products
     * @param user
     * @param payType
     * @return: cn.itsource.pethome.order.domain.ProductOrder
     * @Date: 2020/8/26
     */
    private ProductOrder createProductOrder(Shop shop, List<Map<String, Object>> products, User user, Integer payType) {
        ProductOrder order = new ProductOrder();
        order.setDigest("[服务订单]"+shop.getName()+"进行服务");
        order.setState(0);
        order.setLastPayTime(new Date(System.currentTimeMillis() + 15*60*1000));
        order.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        order.setPaySn(CodeGenerateUtils.generateUnionPaySn());
        order.setUser(user);
        order.setShop(shop);
        BigDecimal totalAmount = new BigDecimal("0");
        for (Map<String, Object> partm : products) {
            Integer id = (Integer) partm.get("id");
            Integer num = (Integer) partm.get("num");
            Product product = productMapper.loadById(Long.valueOf(id));
            BigDecimal saleprice = product.getSaleprice();
            totalAmount = totalAmount.add(saleprice.multiply(new BigDecimal(num)));
        }
        order.setPrice(totalAmount);
        return order;
    }

}
